import strawberry
from app.api.graphql.types import IsOk
from app.common.auth import Login
from app.common.errors import ApiError
from app.common.errors import Error
from app.common.func import decode
from app.models import User as UserModel
from strawberry.types import Info


def get_user_by_info(info: Info) -> UserModel:
    return info.context["request"].state.user


@strawberry.mutation(permission_classes=[Login])
async def block_field(info: Info, user_id: str) -> IsOk:
    current_user = get_user_by_info(info)

    decode_user_id = decode(user_id)
    if not decode_user_id:
        raise ApiError(Error.OBJECT_NOT_EXISTED)

    decode_user_id = int(decode_user_id)

    if current_user.auto_id == decode_user_id:
        raise ApiError(Error.CANNOT_BLOCK_YOURSELF)
    await current_user.block_user_then_unfollow(decode_user_id)

    return IsOk(is_ok=True)


@strawberry.mutation(permission_classes=[Login])
async def unblock_field(info: Info, user_id: str) -> IsOk:
    current_user = get_user_by_info(info)

    decode_user_id = decode(user_id)
    if not decode_user_id:
        raise ApiError(Error.OBJECT_NOT_EXISTED)

    decode_user_id = int(decode_user_id)

    if current_user.auto_id == decode_user_id:
        raise ApiError(Error.CANNOT_UNBLOCK_YOURSELF)
    await current_user.unblock(decode_user_id)

    return IsOk(is_ok=True)


@strawberry.mutation(permission_classes=[Login])
async def follow_field(info: Info, user_id: str) -> IsOk:
    current_user = get_user_by_info(info)
    decode_user_id = decode(user_id)
    if not decode_user_id:
        raise ApiError(Error.OBJECT_NOT_EXISTED)

    decode_user_id = int(decode_user_id)

    if current_user.auto_id == decode_user_id:
        raise ApiError(Error.CANNOT_FOLLOW_YOURSELF)

    if await current_user.has_blocked(decode_user_id):
        raise ApiError(Error.CANNOT_FOLLOW_BLOCKED_USER)

    await current_user.follow(decode_user_id)
    return IsOk(is_ok=True)


@strawberry.mutation(permission_classes=[Login])
async def unfollow_field(info: Info, user_id: str) -> IsOk:
    current_user = get_user_by_info(info)
    decode_user_id = decode(user_id)
    if not decode_user_id:
        raise ApiError(Error.OBJECT_NOT_EXISTED)

    decode_user_id = int(decode_user_id)

    if current_user.auto_id == decode_user_id:
        raise ApiError(Error.CANNOT_UNFOLLOW_YOURSELF)

    await current_user.unfollow(decode_user_id)

    return IsOk(is_ok=True)
